package net.j4love.mybatis.transaction;

import net.j4love.mybatis.dao.UserDAO;
import net.j4love.mybatis.model.User;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.Before;
import org.junit.Test;

import java.io.InputStream;
import java.util.Date;

/**
 * @author He Peng
 * @create 2017-06-24 10:30
 * @update 2017-06-24 10:30
 * @updatedesc : 更新说明
 * @see
 */
public class TransactionIsolationTest {

    private SqlSessionFactory sqlSessionFactory;

    @Before
    public void setUp() throws Exception {
        String resource = "mybatis-config.xml";
        InputStream inputStream = Resources.getResourceAsStream(resource);
        this.sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
    }

    // 第一次对一行数据进行写操作
    @Test
    public void updateFirst() {
        SqlSession sqlSession = this.sqlSessionFactory.openSession();
        String namespace = UserDAO.class.getName();

        User paramUser = new User();
        paramUser.setId(6L);
        User dbUser = sqlSession.selectOne(namespace + "." + "selectByPrimaryKey", paramUser);

        if (null != dbUser) {
            dbUser.setUpdateTime(new Date());
            dbUser.setNickname("star");
            dbUser.setRealname("杰森伯恩");
            dbUser.setPhone(13723236325L);
            dbUser.setLoginPassword("123456789");
            dbUser.setPayPassword("123456");

            try {
                sqlSession.update(namespace + "." + "updateByPrimaryKey" , dbUser);
                Thread.sleep(6 * 1000 * 20);
                sqlSession.commit();
            } catch (Exception e) {
                sqlSession.rollback();
                e.printStackTrace();
            }
        }
    }

    // 第二次对同一行数据进行写操作
    // 当第一次操作该行数据的写操作事务没有提交的时候，这一行数据会被 mysql 锁住
    // (使用 Innodb 引擎时会使用行锁)
    // 之后的写操作会一直等待锁的释放，直到等待锁超时
    @Test
    public void updateSecond() {
        SqlSession sqlSession = this.sqlSessionFactory.openSession();
        String namespace = UserDAO.class.getName();

        User paramUser = new User();
        paramUser.setId(6L);
        User dbUser = sqlSession.selectOne(namespace + "." + "selectByPrimaryKey", paramUser);

        if (null != dbUser) {
            dbUser.setUpdateTime(new Date());
            dbUser.setNickname("facebook");
            dbUser.setRealname("马克扎克伯格");
            dbUser.setPhone(13723236325L);
            dbUser.setLoginPassword("123456789");
            dbUser.setPayPassword("123456");

            try {
                sqlSession.update(namespace + "." + "updateByPrimaryKey" , dbUser);
                sqlSession.commit();
            } catch (Exception e) {
                sqlSession.rollback();
                e.printStackTrace();
            }
        }
    }

    @Test
    public void select() throws Exception {
        SqlSession sqlSession = this.sqlSessionFactory.openSession();
        String namespace = UserDAO.class.getName();
        User paramUser = new User();
        paramUser.setId(6L);
        User dbUser = sqlSession.selectOne(namespace + "." + "selectByPrimaryKey", paramUser);
        if (null != dbUser) {
            System.err.println(dbUser);
        }
    }

}
